package com.chaos.order.api.helper;

import jakarta.servlet.http.HttpServletRequest;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.StringJoiner;

/**
 * 部分代码源于 作者: https://www.cnblogs.com/fanshuyao/
 */
@Deprecated
public class IpUtils {
    private static final String[] HEADERS = {
            "REMOTE_ADDR",
            "X-Real-IP",
            "X-Forwarded-For",
            "Proxy-Client-IP",
            "WL-Proxy-Client-IP",
            "HTTP_X_FORWARDED_FOR",
            "HTTP_X_FORWARDED",
            "HTTP_X_CLUSTER_CLIENT_IP",
            "HTTP_CLIENT_IP",
            "HTTP_FORWARDED_FOR",
            "HTTP_FORWARDED",
            "HTTP_VIA"
    };

    /**
     * 判断ip是否为空，空返回true
     *
     * @param ip ip地址
     * @return
     */
    public static boolean isEmptyIp(final String ip) {
        return (ip == null || ip.length() == 0 || "".equals(ip.trim()) || "unknown".equalsIgnoreCase(ip));
    }


    /**
     * 判断ip是否不为空，不为空返回true
     *
     * @param ip ip地址
     * @return
     */
    public static boolean isNotEmptyIp(final String ip) {
        return !isEmptyIp(ip);
    }

    /***
     * 获取客户端ip地址(可以穿透代理)
     * @param request HttpServletRequest
     * @return 返回IP地址
     */
    public static String getIpAddress(HttpServletRequest request) {
        String ip = "";
        for (String header : HEADERS) {
            ip = request.getHeader(header);
            if (isNotEmptyIp(ip)) {
                break;
            }
        }
        if (isEmptyIp(ip)) {
            ip = request.getRemoteAddr();
        }
        if (isNotEmptyIp(ip) && ip.contains(",")) {
            ip = ip.split(",")[0];
        }
        if ("0:0:0:0:0:0:0:1".equals(ip)) {
            ip = "127.0.0.1";
        }
        return ip;
    }


    /**
     * 获取本机的局域网ip地址，兼容Linux
     *
     * @return 返回IP地址
     */
    public static String getLocalHostIP() {
        Enumeration<NetworkInterface> allNetInterfaces = null;
        try {
            allNetInterfaces = NetworkInterface.getNetworkInterfaces();
        } catch (SocketException e) {
            throw new RuntimeException(e);
        }
        String localHostAddress = "";
        while (allNetInterfaces.hasMoreElements()) {
            NetworkInterface networkInterface = allNetInterfaces.nextElement();
            Enumeration<InetAddress> address = networkInterface.getInetAddresses();
            while (address.hasMoreElements()) {
                InetAddress inetAddress = address.nextElement();
                if (inetAddress instanceof Inet4Address) {
                    localHostAddress = inetAddress.getHostAddress();
                }
            }
        }
        return localHostAddress;
    }

    /**
     * 判断是否是IP
     *
     * @param str
     * @return
     */
    public static boolean isIp(String str) {
        String[] split = str.split("\\.");
        if (split.length != 4) {
            return false;
        }

        for (String part : split) {
            try {
                int n = Integer.parseInt(part);
                if (n < 0 || n > 255) {
                    return false;
                }
            } catch (Exception e) {
                // ignore e
                return false;
            }
        }
        return true;
    }

    /**
     * 判断是否是IP
     *
     * @param n
     * @return
     */
    public static boolean isIp(long n) {
        // 0.0.0.0 -> 255.255.255.255
        return n >= 0 && n <= 4294967295L;
    }

    /**
     * IPV4 地址转化为 long型 表示
     *
     * @param ip
     * @return
     */
    public static long toLong(String ip) {
        if (!isIp(ip)) {
            throw new IllegalArgumentException("输入参数不是一个合法的IP地址, input: " + ip);
        }

        String[] parts = ip.split("\\.");
        long part1 = Long.parseLong(parts[0]) << 24;
        long part2 = Long.parseLong(parts[1]) << 16;
        long part3 = Long.parseLong(parts[2]) << 8;
        long part4 = Long.parseLong(parts[3]);
        return part1 + part2 + part3 + part4;
    }

    /**
     * long型IPV4 地址转化为 字符串 表示
     *
     * @param ip
     * @return
     */
    public static String toString(long ip) {
        if (!isIp(ip)) {
            throw new IllegalArgumentException("输入参数不是一个合法的IP地址, input: " + ip);
        }

        long part1 = ip >>> 24;
        long part2 = ip >>> 16 & 0XFF;
        long part3 = ip >>> 8 & 0XFF;
        long part4 = ip & 0XFF;

        return part1 + "." +
                part2 + "." +
                part3 + "." +
                part4;
    }


    /**
     * ip 二进制表达
     * 形如: 11000000.10101000.00000010.01010111
     * <p>
     * 子网掩码计算
     * https://www.sojson.com/convert/subnetmask.html
     *
     * @param ip
     * @return
     */
    public static String toBinaryString(String ip) {
        if (!isIp(ip)) {
            throw new IllegalArgumentException("输入参数不是一个合法的IP地址, input: " + ip);
        }

        StringJoiner joiner = new StringJoiner(".");

        String[] parts = ip.split("\\.");
        for (String part : parts) {
            StringBuilder binaryString = new StringBuilder(Integer.toBinaryString(Integer.parseInt(part)));
            int lackLength = 8 - binaryString.length();
            if (lackLength > 0) {
                for (int i = 0; i < lackLength; i++) {
                    binaryString.insert(0, "0");
                }
            }
            joiner.add(binaryString.toString());
        }

        return joiner.toString();
    }

    /**
     * 二进制字符串IP转换为普通IP
     * @param binaryString 形如: 11000000.10101000.00000010.01010111
     * @return 形如: 192.168.2.87
     */
    public static String binaryStrIPToNormal(String binaryString) {
        String[] parts = binaryString.split("\\.");

        StringJoiner result = new StringJoiner(".");
        for (String part : parts) {
            int n = Integer.parseInt(part, 2);
            result.add(String.valueOf(n));
        }

        String ip = result.toString();
        if (!isIp(ip)) {
            throw new IllegalArgumentException("输入参数不是一个合法的IP地址, input: " + binaryString);
        }
        return ip;
    }
}
